package com.neuedu.redis.service.impl;

import com.auth0.jwt.JWT;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.neuedu.redis.config.RedisConstants;
import com.neuedu.redis.entity.UmsUser;
import com.neuedu.redis.mapper.UmsUserMapper;
import com.neuedu.redis.service.IUmsUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.neuedu.redis.utils.JWTUtil;
import com.neuedu.redis.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 用户账户表 服务实现类
 * </p>
 *
 * @author 金山
 * @since 2021-06-03
 */
@Service
public class UmsUserServiceImpl extends ServiceImpl<UmsUserMapper, UmsUser> implements IUmsUserService {


    @Autowired
    BCryptPasswordEncoder encoder;

    @Autowired
    RedisUtil redisUtil;



    @Override
    /**
     * - 拿着用户名 现在表中查询
     * - 如果用户名不存在 返回 用户名或密码错误
     * - 如果用户名存在 通过用户名 查询数据库的数据
     * - 然后再进行密码校验 如果密码校验也成功说明可以登录(返回Token),保存到缓存中(key-value)(username:token ,最后一次操作时间)
     * - 如果密码校验不成功 还是用户名或密码错误
     */
    public String token(UmsUser user) throws JsonProcessingException {
        String username = user.getUsername();
        String rawPassword = user.getPassword();//明文的密码

        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",username);
        UmsUser queryUser = this.getOne(queryWrapper);


        String enPassword = queryUser.getPassword();
        if(encoder.matches(rawPassword,enPassword)){
            //可以登录(返回Token),保存到缓存中(key-value)(username:token ,最后一次操作时间)
            String token  = createToken(queryUser);//







            return token;
        }



        return null;
    }

    /**
     * 创建token并 保存缓存
     * @param queryUser
     * @return
     */
    private String createToken(UmsUser queryUser) throws JsonProcessingException {

        queryUser.setLastlogin(LocalDateTime.now());//设置最后一次登录时间

        this.updateById(queryUser);//更新最后一次登录时间


        String token =  JWTUtil.create(queryUser);

        String key = RedisConstants.LOGIN_PREFIX + queryUser.getUsername();

        ObjectMapper mapper =  new ObjectMapper();

        Map user  = new HashMap<>();

        user.put("username",queryUser.getUsername());
        user.put("password",queryUser.getPassword());
        long lastLogin = queryUser.getLastlogin().toInstant(ZoneOffset.of("+8")).toEpochMilli();
        user.put("lastlogin",lastLogin); //162222222222222222222222
        String userJson = mapper.writeValueAsString(user);

        //将登录状态，放到，缓存中，并设置 30分有效
        redisUtil.set(key,userJson,60 * 30);

        return JWTUtil.create(queryUser);
    }
}
